package main

import (
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"
)

func main() {
	goroutineCount := 10
	//exit := make(chan struct{})
	done := make(chan struct{}, goroutineCount)
	var fanout []chan struct{}
	for fanoutIdx := 0; fanoutIdx < goroutineCount; fanoutIdx++ {
		fanout = append(fanout, make(chan struct{}))
	}

	for i := 0; i < len(fanout); i++ {
		go func(command chan struct{}, workerId int) {
			//fmt.Printf("command[%d] address: %p\n", workerId, command)
			for {
				select {
				// 每个协程都在等待exit信号
				case <- command:
					fmt.Println("worker goroutine exit\n", workerId)
					// 收到exit信号后, 往done中写入数据
					done <- struct{}{}
					return

					// 每秒都会发生
				case <-time.After(time.Second * 10):
					fmt.Println("worker goroutine # is working...\n", workerId)
				}
			}
		} (fanout[i], i)
	}

	quit := make(chan os.Signal)
	signal.Notify(quit, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGKILL)
	<-quit

	// 这里用协程来发消息, 原因是: 如果从RabbitMQ之类的消息队列拿任务, 就可以向所有下达任务
	go func(sender []chan struct{}) {
		//fmt.Printf("sender address: %p\n", sender)
		//<-quit

		for _, eachSender := range sender{
			//fmt.Printf("sender[%d] address: %p\n", idx, eachSender)
			eachSender <- struct{}{}
		}
	} (fanout)

	// 主协程发送exit信号,这样每个goroutine都会收到exit信号
	//close(exit)

	for i := 0; i < len(fanout); i++ {
		<-done
	}

	fmt.Println("main goroutine exit")
}
